package com.huilian.iotbox.client.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.huilian.iotbox.aliyun.service.PubService;
import com.huilian.iotbox.client.dao.DeviceDao;
import com.huilian.iotbox.client.producer.RabbitProducer;
import com.huilian.iotbox.client.service.*;
import com.huilian.iotbox.data.cmd.PositiveDataFrameCMD;
import com.huilian.iotbox.data.cmd.VendmachPositiveDataFrameCMD;
import com.huilian.iotbox.data.common.RedisKey;
import com.huilian.iotbox.data.common.ServerResponse;
import com.huilian.iotbox.data.constants.DelayConstants;
import com.huilian.iotbox.data.constants.IotConstant;
import com.huilian.iotbox.data.dto.*;
import com.huilian.iotbox.data.enums.*;
import com.huilian.iotbox.data.po.*;
import com.huilian.iotbox.data.properties.ConfigProperties;
import com.huilian.iotbox.data.service.*;
import com.huilian.iotbox.data.utils.IotBoxUtil;
import com.huilian.iotbox.data.utils.SnowflakeIdWorker;
import com.huilian.iotbox.data.vo.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class DeviceServiceImpl implements DeviceService {

    @Value("${huilian.iot.productKey}")
    private String productKey;
    @Autowired
    private DeviceDao deviceDao;
    @Autowired
    private PubService pubService;
    @Autowired
    private RabbitProducer rabbitProducer;
    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private DisplayRackItemService displayRackItemService;
    @Autowired
    private RedisTemplate<String, Serializable> redisCacheTemplate;
    @Autowired
    private CommodityStoreUpDownService commodityStoreUpDownService;
    @Autowired
    private BlueToothPubService blueToothPubService;
    @Resource
    private OrderService orderService;
    @Resource
    private OrderItemService orderItemService;
    @Autowired
    private ErrorLogCommonService errorLogCommonService;


    @Override
    public DeviceVo findOneDeviceByDeviceNo(String deviceNo) {
        return deviceDao.findOneDeviceByDeviceNo(deviceNo);
    }

    @Override
    public DeviceDto queryByDeviceNo(String deviceNo) {
        return deviceDao.queryByDeviceNo(deviceNo);
    }



    @Override
    public ServerResponse getOneDeviceByDeviceNo(DeviceDto deviceDto) {
        if (StringUtils.isEmpty(deviceDto.getDeviceNo())) {
            return ServerResponse.createByErrorMessage("设备号不能为空");
        }
        DeviceVo deviceVo = this.findOneDeviceByDeviceNo(deviceDto.getDeviceNo());
        if (StringUtils.isEmpty(deviceVo)) {
            return ServerResponse.createByErrorMessage("设备信息有误");
        }

        DeviceVo vo = new DeviceVo();
        vo.setDeviceNo(deviceVo.getDeviceNo());
        vo.setAlias(deviceVo.getAlias());
        vo.setDeviceTypeId(deviceVo.getDeviceTypeId());
        vo.setRateEach(deviceVo.getRateEach());
        vo.setMerchantStoreId(deviceVo.getMerchantStoreId());
        vo.setNetworkIntensity(deviceVo.getNetworkIntensity());
        vo.setIsBluetooth(deviceVo.getIsBluetooth());
        vo.setIsWIfI(deviceVo.getIsWIfI());
        vo.setProductId(deviceVo.getProductId());
        vo.setDeviceTypeName(deviceVo.getDeviceTypeName());
        vo.setPulseSwitchState(deviceVo.getPulseSwitchState());
        vo.setStoreName(StringUtils.isEmpty(deviceVo.getStoreName()) ? "" : deviceVo.getStoreName());
        vo.setStatus(deviceVo.getStatus());
        vo.setUserId(deviceVo.getUserId());
        vo.setIsExchange(deviceVo.getIsExchange());
        vo.setMeasuringUnit(deviceVo.getMeasuringUnit());
        vo.setGameTime(deviceVo.getGameTime());
        vo.setFillInMemberInfo(deviceVo.getFillInMemberInfo());
        vo.setCommodityGroupSwitch(deviceVo.getCommodityGroupSwitch());
        vo.setShoppingCart(deviceVo.getShoppingCart());
        vo.setShoppingCartCapacity(deviceVo.getShoppingCartCapacity());
        vo.setAutoRefund(deviceVo.getAutoRefund());
        vo.setProductDisplayType(deviceVo.getProductDisplayType());
        if (StringUtils.isEmpty(vo.getMeasuringUnit())) {
            SystemConfig systemConfig = systemConfigService.findOneSystemConfigById(1);
            vo.setMeasuringUnit(systemConfig.getDefaultMeasuringUnit());
        }
        //场地业务员ID
        if(!StringUtils.isEmpty(deviceVo.getSalesmanId())){
            vo.setSalesmanId(deviceVo.getSalesmanId());
        }
        // 根据场地和设备设置判断当前设备是否自动投币
        try {
            if (StringUtils.isEmpty(deviceVo.getAutomaticCoin()) && StringUtils.isEmpty(deviceVo.getMerchantAutomaticCoin())) {
                vo.setAutomaticCoin(false);
            } else if (!StringUtils.isEmpty(deviceVo.getAutomaticCoin()) && !StringUtils.isEmpty(deviceVo.getMerchantAutomaticCoin())) {
                if (deviceVo.getMerchantAutomaticCoin() && !deviceVo.getAutomaticCoin()) {
                    vo.setAutomaticCoin(false);
                } else if (!deviceVo.getMerchantAutomaticCoin() && deviceVo.getAutomaticCoin()) {
                    vo.setAutomaticCoin(true);
                } else if (!deviceVo.getMerchantAutomaticCoin() && !deviceVo.getAutomaticCoin()) {
                    vo.setAutomaticCoin(false);
                } else if (deviceVo.getMerchantAutomaticCoin() && deviceVo.getAutomaticCoin()) {
                    vo.setAutomaticCoin(true);
                } else {
                    vo.setAutomaticCoin(false);
                }
            } else if (!StringUtils.isEmpty(deviceVo.getAutomaticCoin()) && deviceVo.getAutomaticCoin()) {
                vo.setAutomaticCoin(true);
            } else if (!StringUtils.isEmpty(deviceVo.getMerchantAutomaticCoin()) && deviceVo.getMerchantAutomaticCoin()) {
                vo.setAutomaticCoin(true);
            } else {
                vo.setAutomaticCoin(false);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 普通扭蛋机有设置直接购买启动的
        if (!StringUtils.isEmpty(deviceVo.getDeviceTypeId()) && DeviceTypeEnum.GASHAPON_MACHINE.getCode().compareTo(deviceVo.getDeviceTypeId()) == 0) {

            DisplayRackItemDto displayRackItemDto = new DisplayRackItemDto();
            displayRackItemDto.setDeviceId(deviceVo.getId());
            displayRackItemDto.setMerchantStoreId(deviceVo.getMerchantStoreId());
            displayRackItemDto.setIsDelete(false);
            displayRackItemDto.setHierarchy(deviceDto.getHierarchy());
            displayRackItemDto.setFreightLane(deviceDto.getFreightLane());
            final DisplayRackItemVo displayRackItemVo = displayRackItemService.findDisplayRackItem(displayRackItemDto);
            if (!StringUtils.isEmpty(displayRackItemVo)) {
                if (!StringUtils.isEmpty(displayRackItemVo.getRateEach())) {
                    vo.setRateEach(displayRackItemVo.getRateEach());
                }

                CommodityStoreUpDown commodityStoreUpDownCondition = new CommodityStoreUpDown();
                commodityStoreUpDownCondition.setCommodityId(displayRackItemVo.getCommodityId());
                commodityStoreUpDownCondition.setMerchantStoreId(deviceVo.getMerchantStoreId());
                commodityStoreUpDownCondition.setDeviceId(deviceVo.getId());
                commodityStoreUpDownCondition.setHierarchy(displayRackItemVo.getHierarchy());
                commodityStoreUpDownCondition.setFreightLane(displayRackItemVo.getFreightLane());
                commodityStoreUpDownCondition.setStatus(CommodityStoreUpDownEnum.GROUNDING.getCode());
                log.info("commodityStoreUpDownCondition:" + JSON.toJSONString(commodityStoreUpDownCondition));
                CommodityStoreUpDown commodityStoreUpDown = commodityStoreUpDownService.findOneCommodityStoreUpDownByCondition(commodityStoreUpDownCondition);
                if (StringUtils.isEmpty(commodityStoreUpDown)) {
                    vo.setPrice(BigDecimal.ZERO);
                } else {
                    vo.setPrice(commodityStoreUpDown.getRetailPrice());
                }
            }
        } else if (!StringUtils.isEmpty(deviceVo.getDeviceTypeId()) && DeviceTypeEnum.ONE_TO_MANY_BOXES.getCode().compareTo(deviceVo.getDeviceTypeId()) == 0) {
            DisplayRackItemDto displayRackItemDto = new DisplayRackItemDto();
            displayRackItemDto.setDeviceId(deviceVo.getId());
            displayRackItemDto.setMerchantStoreId(deviceVo.getMerchantStoreId());
            displayRackItemDto.setIsDelete(false);
            displayRackItemDto.setHierarchy(deviceDto.getHierarchy());
            displayRackItemDto.setFreightLane(deviceDto.getFreightLane());
            final DisplayRackItemVo displayRackItemVo = displayRackItemService.findDisplayRackItem(displayRackItemDto);
            if (!StringUtils.isEmpty(displayRackItemVo)) {
                if (!StringUtils.isEmpty(displayRackItemVo.getRateEach())) {
                    vo.setRateEach(displayRackItemVo.getRateEach());
                }
            }
        }

        return ServerResponse.createBySuccess(vo);
    }


    /**
     * 检查设备（公用）
     *
     * @param deviceNo
     * @return
     */
    @Override
    public ServerResponse checkDevice(String deviceNo) {
        if (StringUtils.isEmpty(deviceNo)) {
            return ServerResponse.createByErrorMessage(ErrorMsgEnum.DEVICE_NOT_FOUND.getMsg());
        }
        DeviceVo device = deviceDao.findOneDeviceByDeviceNo(deviceNo);
        if (StringUtils.isEmpty(device)) {
            return ServerResponse.createByErrorMessage(ErrorMsgEnum.DEVICE_NOT_FOUND.getMsg());
        }

        // 检查设备网络状态是否有问题
        if (device.getNetworkIntensity() <= 0) {
            return ServerResponse.createByErrorMessage(ErrorMsgEnum.INSERT_COIN_FAIL_BY_NO_NETWORK.getMsg());
        }

        // 下架
        if (device.getStatus().equals(DeviceStatusEnum.OFF_LINE.getCode())) {
            return ServerResponse.createByErrorMessage(ErrorMsgEnum.DEVICE_SOLD_OUT.getMsg());
        }

        // 故障
        if (device.getStatus().equals(DeviceStatusEnum.FAULT.getCode())) {
            return ServerResponse.createByErrorMessage(ErrorMsgEnum.DEVICE_MALFUNCTION.getMsg());
        }

        // 未激活
        if (device.getStatus().equals(DeviceStatusEnum.NON_ACTIVATED.getCode())) {
            return ServerResponse.createByErrorMessage("设备未激活，请联系商家");
        }

        // 已解绑
        if (device.getStatus().equals(DeviceStatusEnum.UNBIND.getCode())) {
            return ServerResponse.createByErrorMessage("设备未绑定场地，请联系商家");
        }

        // 维修替换
        if (device.getStatus().equals(DeviceStatusEnum.MAINTAIN.getCode())) {
            return ServerResponse.createByErrorMessage("设备需维修，请联系商家");
        }

        // 未绑定或已解绑
        if (StringUtils.isEmpty(device.getMerchantStoreId()) || device.getMerchantStoreId().compareTo(-1) == 0) {
            return ServerResponse.createByErrorMessage("设备未绑定或已解绑，请联系商家");
        }

        return ServerResponse.createBySuccess(device);
    }


    @Override
    public ServerResponse findDeviceGoodsByDeviceNo(DeviceDto deviceDto) {
        //        PageHelper.orderBy("dri.createTime DESC");

        deviceDto.setEnabled(true);
        deviceDto.setDisplayRackItemStatus(false);
        DeviceVo deviceVo = this.findOneDeviceByDeviceNo(deviceDto.getDeviceNo());


        if (deviceVo.getProductDisplayType() == 1) {
            PageHelper.startPage(deviceDto.getPageNum(), deviceDto.getPageSize(), true);
            List<DeviceDto> list = deviceDao.findDeviceAndCommodityByDeviceNo(deviceDto);
            return ServerResponse.createBySuccess(new PageInfo<>(list));
        }
        // 创建一个映射，用于存储累加后的数据
        Map<String, DeviceDto> resultMap = new HashMap<>();
        List<DeviceDto> list = deviceDao.findDeviceAndCommodityByDeviceNo(deviceDto);
        for (DeviceDto dto : list) {
            if (dto.getStock() > 0) {
                String key = dto.getCommodityId() + "_" + dto.getRetailPrice();
                if (resultMap.containsKey(key)) {
                    // 如果映射中已有相同 key，累加 stock 值
                    DeviceDto existingDto = resultMap.get(key);
                    existingDto.setStock(existingDto.getStock() + dto.getStock());
                } else {
                    // 否则，将当前 dto 添加到映射
                    resultMap.put(key, dto);
                }
            }

        }
        // 将累加后的数据转为列表
        List<DeviceDto> resultList = new ArrayList<>(resultMap.values());
        return ServerResponse.createBySuccess(new PageInfo<>(resultList));
    }

    @Override
    public ServerResponse findGroupNameByDeviceNo(DeviceDto deviceDto) {
        deviceDto.setEnabled(true);
        deviceDto.setDisplayRackItemStatus(false);
        List<DeviceDto> list = deviceDao.findGroupNameByDeviceNo(deviceDto);
        List<DeviceDto> newList = new ArrayList<>();

        for (DeviceDto deviceDto1 : list) {
            if (!ObjectUtils.isEmpty(deviceDto1) && !ObjectUtils.isEmpty(deviceDto1.getCommodityStoreUpDownId())) {
                newList.add(deviceDto1);
            }
        }
        return ServerResponse.createBySuccess(newList);
    }

    @Override
    public List<DeviceVo> findAisleByDeviceNo(DeviceDto deviceDto) {
        DeviceVo productByDeviceNo = deviceDao.findProductByDeviceNo(deviceDto.getDeviceNo());
        if (productByDeviceNo.getMerchantStoreId() != null && productByDeviceNo.getMerchantStoreId() != -1) {
            throw new RuntimeException("设备未解绑!");
        }
        List<DeviceVo> deviceVoList = new ArrayList<>();
        for (int i = 0; i < productByDeviceNo.getHierarchyTotal(); i++) {
            DeviceVo hierarchy = new DeviceVo();
            hierarchy.setHierarchyTotal(i + 1);
            hierarchy.setName("第" + toChineseNumber(hierarchy.getHierarchyTotal()) + "层");
            for (int j = 0; j < productByDeviceNo.getFreightLaneTotal(); j++) {
                DeviceVo freightLane = new DeviceVo();
                freightLane.setLaneNumber((i + 1) * 100 + j + 1);
                freightLane.setFreightLane(j + 1);
                freightLane.setHierarchy(i + 1);
                if (DeviceTypeEnum.BLEND_VENDING_MACHINE.getCode().equals(productByDeviceNo.getDeviceTypeId())) {
                    if (i < productByDeviceNo.getSpringMachineHierarchyTotal()) {
                        freightLane.setDeviceTypeId(DeviceTypeEnum.VENDING_MACHINE.getCode());
                    } else {
                        freightLane.setDeviceTypeId(DeviceTypeEnum.OPEN_DOOR_VENDING_MACHINE.getCode());
                    }
                } else if (DeviceTypeEnum.SCREEN_VENDING_MACHINE.getCode().equals(productByDeviceNo.getDeviceTypeId())) {
                    freightLane.setDeviceTypeId(DeviceTypeEnum.VENDING_MACHINE.getCode());
                } else {
                    freightLane.setDeviceTypeId(productByDeviceNo.getDeviceTypeId());
                }
                hierarchy.getAisleList().add(freightLane);
            }
            deviceVoList.add(hierarchy);
        }
        return deviceVoList;
    }

    @Override
    public Integer findSendDetectionByDeviceNo(DeviceDto deviceDto) {
        DeviceVo productByDeviceNo = deviceDao.findProductByDeviceNo(deviceDto.getDeviceNo());
        if (productByDeviceNo.getMerchantStoreId() != null && productByDeviceNo.getMerchantStoreId() != -1) {
            throw new RuntimeException("设备未解绑,不可进行检测!");
        }
        String detectionKey = String.format(RedisKey.MOTOR_TEST_REFRESH_TIME, productByDeviceNo.getId());
        if (Boolean.TRUE.equals(redisCacheTemplate.hasKey(detectionKey))) {
            throw new RuntimeException("正在电机检测中，请稍后再试");
        }
        redisCacheTemplate.opsForValue().set(detectionKey, deviceDto.getAisleList().size(), deviceDto.getAisleList().size() * 5L, TimeUnit.SECONDS);
        List<DeviceVo> testingList = new ArrayList<>(deviceDto.getAisleList());
        Integer length = deviceDto.getAisleList().size();
        String random;
        if (!StringUtils.isEmpty(productByDeviceNo.getLoginId()) && productByDeviceNo.getLoginId().equals(VendingMachineTypeEnum.ELECTROMAGNETIC_LOCK.getCode())) {
            // 只要是30019的都进入这个协议里面，因为外面已经有主板了，所以只能适配，后期的格子机都用新的协议
            String key = String.format(RedisKey.VENDING_MACHINE_TEST_CLIENT, deviceDto.getDeviceNo());
            // 缓存要点击测试的的参数
            random = org.apache.commons.lang.RandomStringUtils.random(6, true, true);
            String command = PositiveDataFrameCMD.penetrate(VendmachPositiveDataFrameCMD.LatticeShipment(random, deviceDto.getAisleList().get(0).getHierarchy(), deviceDto.getAisleList().get(0).getFreightLane()));
            pubService.pub(command, deviceDto.getDeviceNo(), productKey);
            deviceDto.getAisleList().remove(0);
            if (deviceDto.getAisleList().size() > 0) {
                redisCacheTemplate.opsForValue().set(key, (Serializable) deviceDto.getAisleList(), 10, TimeUnit.MINUTES);
            }
        } else {
            List<OrderItem> orderItemList = new ArrayList<>();
            List<OrderItem> latticeOrderItemList = new ArrayList<>();
            Boolean bool = true;
            Integer time = 30 * 3200;
            for (DeviceVo d : deviceDto.getAisleList()) {
                if (!StringUtils.isEmpty(d.getDeviceTypeId()) && d.getDeviceTypeId().equals(DeviceTypeEnum.OPEN_DOOR_VENDING_MACHINE.getCode())) {
                    OrderItem latticeOrderItem = new OrderItem();
                    latticeOrderItem.setFreightLane(d.getFreightLane());
                    latticeOrderItem.setHierarchy(d.getHierarchy());
                    latticeOrderItem.setNum(1);
                    latticeOrderItemList.add(latticeOrderItem);
                } else {
                    OrderItem orderItem = new OrderItem();
                    orderItem.setFreightLane(d.getFreightLane());
                    orderItem.setHierarchy(d.getHierarchy());
                    orderItem.setNum(1);
                    orderItemList.add(orderItem);
                }

                if (orderItemList.size() == 30) {
                    time = handleShipment(bool, orderItemList, deviceDto, productByDeviceNo.getIsBluetooth(), time, DeviceTypeEnum.VENDING_MACHINE.getCode());
                    orderItemList = new ArrayList<>();
                    bool = false;
                }

                if (latticeOrderItemList.size() == 30) {
                    time = handleShipment(bool, latticeOrderItemList, deviceDto, productByDeviceNo.getIsBluetooth(), time, DeviceTypeEnum.OPEN_DOOR_VENDING_MACHINE.getCode());
                    latticeOrderItemList = new ArrayList<>();
                    bool = false;
                }
            }
            // 处理不足30条的剩余数据
            if (orderItemList.size() > 0) {
                time = handleShipment(bool, orderItemList, deviceDto, productByDeviceNo.getIsBluetooth(), time, DeviceTypeEnum.VENDING_MACHINE.getCode());
                bool = false;
            }
            if (latticeOrderItemList.size() > 0) {
                time = handleShipment(bool, latticeOrderItemList, deviceDto, productByDeviceNo.getIsBluetooth(), time, DeviceTypeEnum.OPEN_DOOR_VENDING_MACHINE.getCode());
            }
        }
        //把要检测货道存起来
        for (DeviceVo d : testingList) {
            final String offlineKey = String.format(RedisKey.MQTT_MOTOR_TESTING_SOCKET_ID, deviceDto.getDeviceNo(), d.getHierarchy(), d.getFreightLane());
            redisCacheTemplate.opsForValue().set(offlineKey, "client_" + deviceDto.getMemberId(), 10, TimeUnit.MINUTES);
            log.info("电机检测socketId:{},key:{}", deviceDto.getSocketId(), offlineKey);
        }
        return length;
    }

    public Integer handleShipment(Boolean bool, List<OrderItem> orderItemList, DeviceDto deviceDto, Boolean isBluetooth, Integer time, Integer deviceTypeId) {
        Map<String, String> delayMap = new HashMap<>();
        if (!StringUtils.isEmpty(isBluetooth) && isBluetooth) {
            String random = RandomStringUtils.random(6, true, true);
            String command = VendmachPositiveDataFrameCMD.LatticeShipmentTestNew(deviceDto.getDeviceNo(), random, orderItemList, LatticeShipmentTestNewCmdEnum.DETECTION.getCode());
            blueToothPubService.pub(command, deviceDto.getDeviceNo(), "client_" + deviceDto.getMemberId());
        } else {
            if (bool) {
                String random = RandomStringUtils.random(6, true, true);
                String data = null;
                if (deviceTypeId.equals(DeviceTypeEnum.OPEN_DOOR_VENDING_MACHINE.getCode())) {
                    data = VendmachPositiveDataFrameCMD.LatticeShipmentTestNew(deviceDto.getDeviceNo(), random, orderItemList, LatticeShipmentTestNewCmdEnum.DETECTION.getCode());
                } else {
                    data = VendmachPositiveDataFrameCMD.motorTesting(deviceDto.getDeviceNo(), random, orderItemList);
                }
                String command = PositiveDataFrameCMD.penetrate(data);
                pubService.pub(command, deviceDto.getDeviceNo(), productKey);
            } else {

                delayMap.put("deviceTypeId", deviceTypeId.toString());
                delayMap.put("deviceNo", deviceDto.getDeviceNo());
                delayMap.put("orderItemList", JSON.toJSONString(orderItemList));
                rabbitProducer.sendMotorDetectionEndLazyQueue(delayMap, time);
                time += orderItemList.size() * 4000;
            }
        }
        return time;
    }


    @Override
    public DeviceVo findByDeviceNo(String deviceNo) {
        return deviceDao.findByDeviceNo(deviceNo);
    }

    @Override
    public DeviceVo findByCpuId(String cpuId) {
        return deviceDao.findByCpuId(cpuId);
    }


    @Override
    public void update(DeviceDto deviceDto) {
        deviceDao.update(deviceDto);
    }

    @Override
    public List<DeviceVo> findDeviceByMerchantStoreId(Integer merchantStoreId) {
        return deviceDao.findDeviceByMerchantStoreId(merchantStoreId);
    }

    @Override
    public void bluetoothTestResults(String protocol) {
        System.out.println(protocol.substring(10, 26));
        int deviceNo = IotBoxUtil.singleHex2Int(protocol.substring(10, 26));
        StringBuilder stringBuilder = new StringBuilder(IotConstant.CONTENT_PREFIX);
        stringBuilder.append("1C0126");
        stringBuilder.append(protocol);
        stringBuilder.append("4C");
        stringBuilder.append(IotConstant.CONTENT_SUFFIX);
        pubService.pub(String.valueOf(stringBuilder), Integer.toString(deviceNo), productKey, true);
    }

    @Override
    public ServerResponse bluetoothReShipment(DeviceDto deviceDto) {
        String key = String.format(RedisKey.BLUETOOTH_RE_SHIPPING,deviceDto.getDeviceNo(),deviceDto.getOutTradeNo());
        if (!Boolean.TRUE.equals(redisCacheTemplate.hasKey(key))){
            return ServerResponse.createByErrorMessage("订单已超过二十分钟限制,不可重新出货");
        }
        Integer orderIdInt = (Integer) redisCacheTemplate.opsForValue().get(key);
        long orderId = (long) orderIdInt;
        Order order = orderService.findById(orderId);
        if (StringUtils.isEmpty(order)){
            return ServerResponse.createByErrorMessage("异常:订单不存在");
        }
        if (!OrderStatusEnum.SUCCESS.getCode().equals(order.getStatus())){
            return ServerResponse.createByErrorMessage("仅支付成功的订单可重新出货");
        }
        if (ShipmentStatusEnum.SUCCESS.getCode().equals(order.getShipmentStatus())){
            return ServerResponse.createByErrorMessage("订单已全部出货成功,无需重新出货");
        }
        if (ShipmentStatusEnum.WAIT.getCode().equals(order.getShipmentStatus())){
            return ServerResponse.createByErrorMessage("订单正在处理中,请稍后尝试");
        }
        if (ShipmentStatusEnum.PART_FAIL.getCode().equals(order.getShipmentStatus()) || ShipmentStatusEnum.FAIL.getCode().equals(order.getShipmentStatus())){
            List<OrderItem> orderItems = orderItemService.getOrderItemById(orderId);
            //修改订单出货状态为待出货再重新发起出货
            Order updateOrder = new Order();
            updateOrder.setOutTradeNo(order.getOutTradeNo());
            updateOrder.setTotalAmount(order.getTotalAmount());
            updateOrder.setShipmentStatus(ShipmentStatusEnum.WAIT.getCode());
            orderService.updateOrder(updateOrder);
            //出货失败的商品
            List<OrderItem> shippingGoodsList = new ArrayList<>();
            for (OrderItem orderItem : orderItems) {
                if (ShipmentStatusEnum.FAIL.getCode().equals(orderItem.getShipmentStatus())){
                    OrderItem updateOrderItem = new OrderItem();
                    updateOrderItem.setId(orderItem.getId());
                    updateOrderItem.setShipmentStatus(ShipmentStatusEnum.WAIT.getCode());
                    orderItemService.update(updateOrderItem);

                    // 查询货道信息,再扣库存
                    DisplayRackItemDto selectFindDisplayRackItem = DisplayRackItemDto.builder()
                            .hierarchy(orderItem.getHierarchy())
                            .freightLane(orderItem.getFreightLane())
                            .isDelete(false)
                            .deviceId(deviceDto.getDeviceId())
                            .build();
                    DisplayRackItemVo displayRackItem = displayRackItemService.findDisplayRackItem(selectFindDisplayRackItem);
                    DisplayRackItemDto updateDto = new DisplayRackItemDto();
                    updateDto.setStock(displayRackItem.getStock() - orderItem.getNum());
                    updateDto.setId(displayRackItem.getId());
                    updateDto.setVersion(displayRackItem.getVersion());
                    displayRackItemService.updateStockById(updateDto);
                    shippingGoodsList.add(orderItem);
                }
            }

            String  command = VendmachPositiveDataFrameCMD.LatticeShipmentTestNew(deviceDto.getDeviceNo(), order.getPayNo(), shippingGoodsList, LatticeShipmentTestNewCmdEnum.SHIPPING.getCode());
            boolean sendResult = blueToothPubService.pub(command,deviceDto.getDeviceNo(),"client_"+order.getMemberId());
            if (!sendResult) {
                errorLogCommonService.writerInfoErrorLog("售货机指令发送失败" + command, order);
                return ServerResponse.createByErrorMessage("重新出货发起失败");
            }
            final SystemConfig systemConfig = systemConfigService.findOneSystemConfigById(1);
            rabbitProducer.sendVendingMachineReplayLazyQueue(DelayConstants.VENDING_MACHINE, order, 1000 * systemConfig.getOnLineInsertCoinNotNoticeTime());
        }
        return ServerResponse.createBySuccess();
    }

    @Override
    public ServerResponse setBatteryNumber(DeviceDto deviceDto) {
        DeviceVo deviceVo = deviceDao.findDeviceByDeviceNo(deviceDto.getDeviceNo());
        if (StringUtils.isEmpty(deviceVo)) {
            throw new RuntimeException(deviceDto.getDeviceNo() + "不存在");
        }
        if(!StringUtils.isEmpty(deviceVo.getBatteryNumber())){
            String command = VendmachPositiveDataFrameCMD.setBatteryNumber(deviceDto.getDeviceNo(),deviceVo.getBatteryNumber());
            return ServerResponse.createBySuccess(command);
        }else{
            return ServerResponse.createByError();
        }


    }


    public static String toChineseNumber(Integer num) {
        if (num == 0) {
            return "零";
        }

        String[] chineseDigits = {"", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
        String[] chineseTenDigits = {"", "十", "二十", "三十", "四十", "五十", "六十", "七十", "八十", "九十"};

        if (num < 10) {
            return chineseDigits[num];
        } else if (num < 20) {
            return "十" + chineseDigits[num - 10];
        } else {
            int tenDigit = num / 10;
            int unitDigit = num % 10;
            if (unitDigit == 0) {
                return chineseTenDigits[tenDigit];
            } else {
                return chineseTenDigits[tenDigit] + chineseDigits[unitDigit];
            }
        }
    }

    public static void main(String[] args) {
//        // 单价
//        BigDecimal price = BigDecimal.valueOf(1);
//        // 推荐方案
//        BigDecimal p = BigDecimal.valueOf(1);
//        System.out.println(p.divide(price, 1, BigDecimal.ROUND_HALF_UP).intValue());

        DeviceVo deviceVo = new DeviceVo();
        deviceVo.setAutomaticCoin(false);
        deviceVo.setMerchantAutomaticCoin(true);

        DeviceVo vo = new DeviceVo();
        if (StringUtils.isEmpty(deviceVo.getAutomaticCoin()) && StringUtils.isEmpty(deviceVo.getMerchantAutomaticCoin())) {
            vo.setAutomaticCoin(false);
            System.out.println(1);
        } else if (!StringUtils.isEmpty(deviceVo.getAutomaticCoin()) && !StringUtils.isEmpty(deviceVo.getMerchantAutomaticCoin())) {
            if (deviceVo.getMerchantAutomaticCoin() && !deviceVo.getAutomaticCoin()) {
                vo.setAutomaticCoin(false);
                System.out.println(4);
            } else if (!deviceVo.getMerchantAutomaticCoin() && deviceVo.getAutomaticCoin()) {
                vo.setAutomaticCoin(true);
                System.out.println(5);
            } else if (!deviceVo.getMerchantAutomaticCoin() && !deviceVo.getAutomaticCoin()) {
                vo.setAutomaticCoin(false);
                System.out.println(7);
            }
        } else if (!StringUtils.isEmpty(deviceVo.getAutomaticCoin()) && deviceVo.getAutomaticCoin()) {
            vo.setAutomaticCoin(true);
            System.out.println(2);
        } else if (!StringUtils.isEmpty(deviceVo.getMerchantAutomaticCoin()) && deviceVo.getMerchantAutomaticCoin()) {
            vo.setAutomaticCoin(true);
            System.out.println(3);
        } else {
            vo.setAutomaticCoin(false);
            System.out.println(6);
        }

        System.out.println(vo.getAutomaticCoin());
    }

    /**
     * 推荐充电方案
     */
    @Data
    class RecommendedChargingScheme {
        // 1充到满，2推荐方案，3自定义金额
        private Integer type;
        // 金额
        private BigDecimal money;
        // 充电时间（小时）
        private Integer chargingTime;
        // 费率阶梯ID
        private Long chargingPileRateStageId;
    }


}
